// utils/upload-service.js
const { getApiUrl } = require('../config/config.js');

/**
 * 文件上传服务类
 */
class UploadService {
  constructor() {
    this.baseUrl = getApiUrl('/upload/file');
    this.defaultConfig = {
      timeout: 30000, // 30秒超时
      maxSize: 10 * 1024 * 1024, // 10MB最大文件大小
      allowedTypes: {
        image: ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'],
        document: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'],
        audio: ['mp3', 'wav', 'aac', 'm4a'],
        video: ['mp4', 'avi', 'mov', 'wmv', 'flv'],
        other: ['zip', 'rar', '7z']
      }
    };
  }

  /**
   * 自动检测文件类型
   * @param {string} fileName 文件名
   * @returns {string} 文件类型
   */
  detectFileType(fileName) {
    if (!fileName) return 'other';
    
    const extension = fileName.split('.').pop().toLowerCase();
    
    for (const [type, extensions] of Object.entries(this.defaultConfig.allowedTypes)) {
      if (extensions.includes(extension)) {
        return type;
      }
    }
    
    return 'other';
  }

  /**
   * 生成文件夹路径
   * @param {string} fileType 文件类型
   * @returns {string} 文件夹路径
   */
  generateFolderPath(fileType) {
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');
    
    return `${fileType}/${year}/${month}/${day}`;
  }

  /**
   * 验证文件
   * @param {string} filePath 文件路径
   * @param {number} fileSize 文件大小
   * @returns {Object} 验证结果
   */
  validateFile(filePath, fileSize) {
    const result = {
      valid: true,
      error: null
    };

    // 检查文件大小
    if (fileSize > this.defaultConfig.maxSize) {
      result.valid = false;
      result.error = `文件大小不能超过 ${this.defaultConfig.maxSize / 1024 / 1024}MB`;
      return result;
    }

    // 检查文件类型
    const fileName = filePath.split('/').pop();
    const extension = fileName.split('.').pop().toLowerCase();
    const allExtensions = Object.values(this.defaultConfig.allowedTypes).flat();
    
    if (!allExtensions.includes(extension)) {
      result.valid = false;
      result.error = `不支持的文件类型: ${extension}`;
      return result;
    }

    return result;
  }

  /**
   * 上传单个文件
   * @param {string} filePath 文件路径
   * @param {Object} options 上传选项
   * @returns {Promise} 上传结果
   */
  uploadFile(filePath, options = {}) {
    return new Promise((resolve, reject) => {
      // 获取文件信息
      wx.getFileInfo({
        filePath,
        success: (fileInfo) => {
          // 验证文件
          const validation = this.validateFile(filePath, fileInfo.size);
          if (!validation.valid) {
            reject(new Error(validation.error));
            return;
          }

          // 自动检测文件类型
          const fileName = filePath.split('/').pop();
          const fileType = options.fileType || this.detectFileType(fileName);
          const folder = options.folder || this.generateFolderPath(fileType);

          // 执行上传
          wx.uploadFile({
            url: this.baseUrl,
            filePath,
            name: 'file',
            formData: {
              fileType,
              folder
            },
            timeout: this.defaultConfig.timeout,
            success: (res) => {
              try {
                const data = JSON.parse(res.data);
                if (data.code === 0) {
                  resolve({
                    success: true,
                    data: data.data,
                    url: data.data.url || data.data.fileUrl,
                    fileName: fileName,
                    fileType: fileType,
                    fileSize: fileInfo.size
                  });
                } else {
                  reject(new Error(data.message || '上传失败'));
                }
              } catch (error) {
                reject(new Error('响应数据解析失败'));
              }
            },
            fail: (error) => {
              console.error('文件上传失败:', error);
              reject(new Error(error.errMsg || '网络错误，上传失败'));
            }
          });
        },
        fail: (error) => {
          reject(new Error('获取文件信息失败'));
        }
      });
    });
  }

  /**
   * 批量上传文件
   * @param {Array} filePaths 文件路径数组
   * @param {Object} options 上传选项
   * @returns {Promise} 上传结果
   */
  async uploadMultipleFiles(filePaths, options = {}) {
    const results = [];
    const errors = [];

    for (let i = 0; i < filePaths.length; i++) {
      try {
        const result = await this.uploadFile(filePaths[i], options);
        results.push(result);
        
        // 触发进度回调
        if (options.onProgress) {
          options.onProgress({
            current: i + 1,
            total: filePaths.length,
            progress: Math.round(((i + 1) / filePaths.length) * 100)
          });
        }
      } catch (error) {
        errors.push({
          filePath: filePaths[i],
          error: error.message
        });
      }
    }

    return {
      success: errors.length === 0,
      results,
      errors,
      total: filePaths.length,
      successCount: results.length,
      failureCount: errors.length
    };
  }
}

// 导出单例
const uploadService = new UploadService();

module.exports = {
  UploadService,
  uploadService
};